import std.stdio;
import core.thread;
import std.functional;
public import std.traits;

class AA
{
    void show(int i)
    {
        writeln("i = ", i); // the value is not(0,1,2,3), it all is 2.
    }
    
    void show(int i, int b)
    {
        b += i * 10;
        writeln("b = ", b); // the value is not(0,1,2,3), it all is 2.
    }
    
    void aa()
    {
         writeln("aaaaaaaa "); 
    }
}


void listRun(int i)
{
     writeln("i = ", i); 
}

void list()
{
    writeln("bbbbbbbbbbbb");
}

void dooo(Thread[] t1, Thread[] t2, AA a)
{
    foreach (i ; 0..4) {
        auto th = new Thread(bind!(void delegate(int,int))(&a.show,i,i));
        t1[i]= th;
        auto th2 = new Thread(bind(&listRun,(i + 10)));
        t2[i]= th2;
    }
}

void main() {
    Thread[4] _thread;
    Thread[4] _thread2;
     AA a = new AA();
    
    dooo(_thread,_thread2,a);
    
    foreach(i;0..4)
    {
        _thread[i].start();
    }
    
    foreach(i;0..4)
    {
        _thread2[i].start();
    }
    
}


auto bind(T, Args...)(T fun,Args args) if (isCallable!(T))//if (isDelegate!T)
{
    static if(is(Args == void)) {
        static if(isDelegate!T)
            return fun;
        else
            return toDelegate(fun);
    } else{
	return delegate(){return fun(forward!args);};
    }
}
/*
auto bind(alias Fun,Args...)(Args args) {
	return delegate(){return Fun(forward!args);};
}

*/
